home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 2
/
AACD 2.iso
/
AACD
/
Magazine
/
GraphicsCards
/
StormMesa
/
src
/
Windows
/
wmesa_stereo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-04
|
46KB
|
1,873 lines
/*
WMesa_stereo.c
*/
// Stereo display feature added by Li Wei
// Updated 1996/10/06 11:16:15 CST
// Paralell render feature added by Li Wei
// liwei@aiar.xjtu.edu.cn
// http://sun.aiar.xjtu.edu.cn
#define WMESA_STEREO_C
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wmesadef.h>
#include <GL\wmesa.h>
#include "context.h"
#include "dd.h"
#include "xform.h"
#include "vb.h"
#include "matrix.h"
#include "depth.h"
#ifdef PROFILE
#include "profile.h"
#endif
#include <wing.h>
// Code added by Li Wei to enable stereo display and Paralell render
/*#include "mesa_extend.h"*/
#if !defined(NO_STEREO)
#include "gl\glu.h"
#include "stereo.h"
PBYTE Buffer_Stereo;
void WMesaCreateStereoBuffer(void);
void WMesaInterleave( GLenum aView);
void WMesaDestroyStereoBuffer(void);
void WMesaShowStereo(GLuint list);
#endif
#if !defined(NO_PARALLEL)
#include "parallel.h"
#endif
/* end of added code*/
/* Bit's used for dest: */
#define FRONT_PIXMAP 1
#define BACK_PIXMAP 2
#define BACK_XIMAGE 4
static PWMC Current = NULL;
WMesaContext WC = NULL;
#ifdef NDEBUG
#define assert(ignore) ((void) 0)
#else
void Mesa_Assert(void *Cond,void *File,unsigned Line)
{
char Msg[512];
sprintf(Msg,"%s %s %d",Cond,File,Line);
MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
exit(1);
}
#define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
#endif
#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
#define DD_RELEASEDC
//#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
#define BEGINGDICALL
//#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
#define ENDGDICALL
#define FLIP(Y) (Current->height-(Y)-1)
#define STARTPROFILE
#define ENDPROFILE(PARA)
static void FlushToFile(PWMC pwc, PSTR szFile);
BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
BOOL wmDeleteBackingStore(PWMC pwc);
void wmCreatePalette( PWMC pwdc );
BOOL wmSetDibColors(PWMC pwc);
void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
void wmCreateDIBSection(
HDC hDC,
PWMC pwc, // handle of device context
CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
UINT iUsage // color data type indicator: RGB values or palette indices
);
BOOL wmFlush(PWMC pwc);
/*
* Useful macros:
Modified from file osmesa.c
*/
#define PIXELADDR(X,Y) ((GLbyte *)Current->pbPixels + (Current->height-Y)* Current->ScanWidth + (X)*nBypp)
/* Finish all pending operations and synchronize. */
static void finish(GLcontext* ctx)
{
/* no op */
}
//
// We cache all gl draw routines until a flush is made
//
static void flush(GLcontext* ctx)
{
STARTPROFILE
if(Current->rgb_flag && !(Current->dib.fFlushed)&&!(Current->db_flag)){
wmFlush(Current);
}
ENDPROFILE(flush)
}
/*
* Set the color index used to clear the color buffer.
*/
static void clear_index(GLcontext* ctx, GLuint index)
{
STARTPROFILE
Current->clearpixel = index;
ENDPROFILE(clear_index)
}
/*
* Set the color used to clear the color buffer.
*/
static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
{
STARTPROFILE
Current->clearpixel=RGB(r, g, b );
ENDPROFILE(clear_color)
}
/*
* Clear the specified region of the color buffer using the clear color
* or index as specified by one of the two functions above.
*/
static void clear(GLcontext* ctx,
GLboolean all,GLint x, GLint y, GLint width, GLint height )
{
DWORD dwColor;
WORD wColor;
LPDWORD lpdw = (LPDWORD)Current->pbPixels;
LPWORD lpw = (LPWORD)Current->pbPixels;
LPBYTE lpb = Current->pbPixels;
STARTPROFILE
if (all){
x=y=0;
width=Current->width;
height=Current->height;
}
if (Current->rgb_flag==GL_TRUE){
if(Current->db_flag==GL_TRUE){
UINT nBypp = Current->cColorBits / 8;
int i = 0;
int iSize;
if(nBypp == 2){
iSize = (Current->width * Current->height) / nBypp;
wColor = BGR16(GetRValue(Current->clearpixel),
GetGValue(Current->clearpixel),
GetBValue(Current->clearpixel));
dwColor = MAKELONG(wColor, wColor);
}
else if(nBypp == 4){
iSize = (Current->width * Current->height);
dwColor = BGR32(GetRValue(Current->clearpixel),
GetGValue(Current->clearpixel),
GetBValue(Current->clearpixel));
}
//
// This is the 24bit case
//
else {
iSize = (Current->width * Current->height) / nBypp;
dwColor = BGR24(GetRValue(Current->clearpixel),
GetGValue(Current->clearpixel),
GetBValue(Current->clearpixel));
while(i < iSize){
*lpdw = dwColor;
lpb += nBypp;
lpdw = (LPDWORD)lpb;
i++;
}
// ENDPROFILE(clear)
return;
}
while(i < iSize){
*lpdw = dwColor;
lpdw++;
i++;
}
}
else{ // For single buffer
HDC DC=DD_GETDC;
HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
HPEN Old_Pen=SelectObject(DC,Pen);
HBRUSH Old_Brush=SelectObject(DC,Brush);
Rectangle(DC,x,y,x+width,y+height);
SelectObject(DC,Old_Pen);
SelectObject(DC,Old_Brush);
DeleteObject(Pen);
DeleteObject(Brush);
DD_RELEASEDC;
}
}
else {
int i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
for (i=0; i<height; i++){
memset(Mem,Current->clearpixel,width);
Mem+=width;
}
}
ENDPROFILE(clear)
}
/* Set the current color index. */
static void set_index(GLcontext* ctx, GLuint index)
{
STARTPROFILE
Current->pixel=index;
ENDPROFILE(set_index)
}
/* Set the current RGBA color. */
static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
{
STARTPROFILE
Current->pixel = RGB( r, g, b );
ENDPROFILE(set_color)
}
/* Set the index mode bitplane mask. */
static GLboolean index_mask(GLcontext* ctx, GLuint mask)
{
/* can't implement */
return GL_FALSE;
}
/* Set the RGBA drawing mask. */
static GLboolean color_mask( GLcontext* ctx,
GLboolean rmask, GLboolean gmask,
GLboolean bmask, GLboolean amask)
{
/* can't implement */
return GL_FALSE;
}
/*
* Set the pixel logic operation. Return GL_TRUE if the device driver
* can perform the operation, otherwise return GL_FALSE. If GL_FALSE
* is returned, the logic op will be done in software by Mesa.
*/
GLboolean logicop( GLcontext* ctx, GLenum op )
{
/* can't implement */
return GL_FALSE;
}
static void dither( GLcontext* ctx, GLboolean enable )
{
/* No op */
}
static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
{
STARTPROFILE
/* TODO: this could be better */
if (mode==GL_FRONT || mode==GL_BACK) {
return GL_TRUE;
}
else {
return GL_FALSE;
}
ENDPROFILE(set_buffer)
}
/* Return characteristics of the output buffer. */
static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)
{
int New_Size;
RECT CR;
STARTPROFILE
GetClientRect(Current->Window,&CR);
*width=CR.right;
*height=CR.bottom;
// *depth = Current->depth;
New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
if (New_Size){
Current->width=*width;
Current->height=*height;
Current->ScanWidth=Current->width;
if ((Current->ScanWidth%sizeof(long))!=0)
Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
if (Current->db_flag){
if (Current->rgb_flag==GL_TRUE){
wmDeleteBackingStore(Current);
wmCreateBackingStore(Current, Current->width, Current->height);
}
else{
Current->ScanWidth=Current->width;
if ((Current->ScanWidth%sizeof(long))!=0)
Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
Current->IndexFormat->bmiHeader.biWidth=Current->width;
if (Current->IndexFormat->bmiHeader.biHeight<0)
Current->IndexFormat->bmiHeader.biHeight=-(Current->height);
else
Current->IndexFormat->bmiHeader.biHeight=Current->height;
Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem));
DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM));
}
//Code added by Li Wei to enable stereo display
// Recreate stereo buffer when stereo_flag is TRUE while parallelFlag is FALSE
#if !defined(NO_STEREO)
if(stereo_flag
#if !defined(NO_PARALLEL)
&&!parallelFlag
#endif
) {
if(stereoBuffer == GL_TRUE)
WMesaDestroyStereoBuffer();
WMesaCreateStereoBuffer();
}
#endif
// Resize OsmesaBuffer if in Parallel mode
#if !defined(NO_PARALLEL)
if(parallelFlag)
PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
#endif
//end modification
}
}
ENDPROFILE(buffer_size)
}
/**********************************************************************/
/***** Accelerated point, line, polygon rendering *****/
/**********************************************************************/
static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
{
GLuint i;
// HDC DC=DD_GETDC;
PWMC pwc = Current;
STARTPROFILE
if (Current->gl_ctx->VB->MonoColor) {
/* all drawn with current color */
for (i=first;i<=last;i++) {
if (Current->gl_ctx->VB->ClipMask[i]==0) {
int x, y;
x = (GLint) Current->gl_ctx->VB->Win[i][0];
y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
GetGValue(Current->pixel), GetBValue(Current->pixel));
}
}
}
else {
/* draw points of different colors */
for (i=first;i<=last;i++) {
if (Current->gl_ctx->VB->ClipMask[i]==0) {
int x, y;
unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
Current->gl_ctx->VB->Color[i][1]*255.0,
Current->gl_ctx->VB->Color[i][2]*255.0);
x = (GLint) Current->gl_ctx->VB->Win[i][0];
y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,
Current->gl_ctx->VB->Color[i][1]*255.0,
Current->gl_ctx->VB->Color[i][2]*255.0);
}
}
}
// DD_RELEASEDC;
ENDPROFILE(fast_rgb_points)
}
/* Return pointer to accerated points function */
extern points_func choose_points_function( GLcontext* ctx )
{
STARTPROFILE
if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
&& !ctx->Texture.Enabled && ctx->Visual->RGBAflag) {
ENDPROFILE(choose_points_function)
return fast_rgb_points;
}
else {
ENDPROFILE(choose_points_function)
return NULL;
}
}
/* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
{
STARTPROFILE
int x0, y0, x1, y1;
unsigned long pixel;
HDC DC=DD_GETDC;
HPEN Pen;
HPEN Old_Pen;
if (Current->gl_ctx->VB->MonoColor) {
pixel = Current->pixel; /* use current color */
}
else {
pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
}
x0 = (int) Current->gl_ctx->VB->Win[v0][0];
y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
x1 = (int) Current->gl_ctx->VB->Win[v1][0];
y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
BEGINGDICALL
Pen=CreatePen(PS_SOLID,1,pixel);
Old_Pen=SelectObject(DC,Pen);
MoveToEx(DC,x0,y0,NULL);
LineTo(DC,x1,y1);
SelectObject(DC,Old_Pen);
DeleteObject(Pen);
DD_RELEASEDC;
ENDGDICALL
ENDPROFILE(fast_flat_rgb_line)
}
/* Return pointer to accerated line function */
static line_func choose_line_function( GLcontext* ctx )
{
STARTPROFILE
if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
&& ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
&& !ctx->Texture.Enabled && Current->rgb_flag) {
ENDPROFILE(choose_line_function)
return fast_flat_rgb_line;
}
else {
ENDPROFILE(choose_line_function)
return NULL;
}
}
/**********************************************************************/
/***** Optimized triangle rendering *****/
/**********************************************************************/
/*
* Smooth-shaded, z-less triangle, RGBA color.
*/
static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv )
{
UINT nBypp = Current->cColorBits / 8;
GLbyte* img;
GLushort* img16;
GLuint *img24 ,*img32;
#define INTERP_Z 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INNER_LOOP( LEFT, RIGHT, Y ) \
{ \
GLint i, len = RIGHT-LEFT; \
img = PIXELADDR(LEFT,Y); \
for (i=0;i<len;i++,img+=nBypp) { \
GLdepth z = FixedToDepth(ffz); \
if (z < zRow[i]) { \
img16 = img24 = img32 = img; \
if(nBypp == 2) \
*img16 = BGR16( FixedToInt(ffr), FixedToInt(ffg), \
FixedToInt(ffb)); \
if(nBypp == 3) \
*img24 = BGR24( FixedToInt(ffr), FixedToInt(ffg), \
FixedToInt(ffb)); \
if(nBypp == 4) \
*img32 = BGR32( FixedToInt(ffr), FixedToInt(ffg), \
FixedToInt(ffb)); \
zRow[i] = z; \
} \
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
ffz += fdzdx; \
} \
}
#include "tritemp.h"
}
/*
* Flat-shaded, z-less triangle, RGBA color.
*/
static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
GLuint v2, GLuint pv )
{
GLbyte* img;
GLushort* img16;
GLuint *img24, *img32;
UINT nBypp = Current->cColorBits / 8;
GLubyte r, g, b ;
GLushort pixel16 = BGR16(r,g,b);
GLuint pixel24 = BGR24(r,g,b);
GLuint pixel32 = BGR32(r,g,b);
#define INTERP_Z 1
#define SETUP_CODE \
r = VB->Color[pv][0]; \
g = VB->Color[pv][1]; \
b = VB->Color[pv][2];
#define INNER_LOOP( LEFT, RIGHT, Y ) \
{ \
GLint i, len = RIGHT-LEFT; \
img = PIXELADDR(LEFT,Y); \
for (i=0;i<len;i++,img+=nBypp) { \
GLdepth z = FixedToDepth(ffz); \
if (z < zRow[i]) { \
img16 = img24 = img32 = img; \
if(nBypp == 2) \
*img16 = pixel16; \
if(nBypp == 3) \
*img24 = pixel24; \
if(nBypp == 4) \
*img32 = pixel32; \
zRow[i] = z; \
} \
ffz += fdzdx; \
} \
}
#include "tritemp.h"
}
/*
* Return pointer to an accelerated triangle function if possible.
*/
static triangle_func choose_triangle_function( GLcontext *ctx )
{
if (ctx->Polygon.SmoothFlag) return NULL;
if (ctx->Polygon.StippleFlag) return NULL;
if (ctx->Texture.Enabled) return NULL;
if (ctx->RasterMask==DEPTH_BIT
&& ctx->Depth.Func==GL_LESS
&& ctx->Depth.Mask==GL_TRUE
&& ctx->Visual->RGBAflag) {
if (ctx->Light.ShadeModel==GL_SMOOTH) {
return smooth_color_z_triangle;
}
else {
return flat_color_z_triangle;
}
}
return NULL;
}
/* Draw a convex polygon using color Current->gl_ctx->VB->Color[pv] */
static void fast_flat_rgb_polygon( GLcontext* ctx, GLuint n, GLuint vlist[], GLuint pv )
{
STARTPROFILE
POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
HDC DC=DD_GETDC;
HPEN Pen;
HBRUSH Brush;
HPEN Old_Pen;
HBRUSH Old_Brush;
GLint pixel;
GLuint i;
if (Current->gl_ctx->VB->MonoColor) {
pixel = Current->pixel; /* use current color */
}
else {
pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
}
Pen=CreatePen(PS_SOLID,1,pixel);
Brush=CreateSolidBrush(pixel);
Old_Pen=SelectObject(DC,Pen);
Old_Brush=SelectObject(DC,Brush);
for (i=0; i<n; i++) {
int j = vlist[i];
Pts[i].x = (int) Current->gl_ctx->VB->Win[j][0];
Pts[i].y = FLIP( (int) Current->gl_ctx->VB->Win[j][1] );
}
BEGINGDICALL
Polygon(DC,Pts,n);
SelectObject(DC,Old_Pen);
SelectObject(DC,Old_Brush);
DeleteObject(Pen);
DeleteObject(Brush);
DD_RELEASEDC;
free(Pts);
ENDGDICALL
ENDPROFILE(fast_flat_rgb_polygon)
}
/* Return pointer to accerated polygon function */
static polygon_func choose_polygon_function( GLcontext* ctx )
{
STARTPROFILE
if (!ctx->Polygon.SmoothFlag && !ctx->Polygon.StippleFlag
&& ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
&& !ctx->Texture.Enabled && Current->rgb_flag==GL_TRUE) {
ENDPROFILE(choose_polygon_function)
return fast_flat_rgb_polygon;
}
else {
ENDPROFILE(choose_polygon_function)
return NULL;
}
}
/**********************************************************************/
/***** Span-based pixel drawing *****/
/**********************************************************************/
/* Write a horizontal span of color-index pixels with a boolean mask. */
static void write_index_span( GLcontext* ctx,
GLuint n, GLint x, GLint y,
const GLuint index[],
const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++)
if (mask[i])
Mem[i]=index[i];
ENDPROFILE(write_index_span)
}
/*
* Write a horizontal span of pixels with a boolean mask. The current
* color index is used for all pixels.
*/
static void write_monoindex_span(GLcontext* ctx,
GLuint n,GLint x,GLint y,
const GLubyte mask[])
{
STARTPROFILE
GLuint i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++)
if (mask[i])
Mem[i]=Current->pixel;
ENDPROFILE(write_monoindex_span)
}
/*
To improve the performance of this routine, frob the data into an actual scanline
and call bitblt on the complete scan line instead of SetPixel.
*/
/* Write a horizontal span of color pixels with a boolean mask. */
static void write_color_span( GLcontext* ctx,
GLuint n, GLint x, GLint y,
const GLubyte
red[], const GLubyte green[],
const GLubyte blue[], const GLubyte alpha[],
const GLubyte mask[] )
{
STARTPROFILE
PWMC pwc = Current;
if (pwc->rgb_flag==GL_TRUE)
{
GLuint i;
HDC DC=DD_GETDC;
y=FLIP(y);
if (mask) {
for (i=0; i<n; i++)
if (mask[i])
wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
}
else {
for (i=0; i<n; i++)
wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
}
DD_RELEASEDC;
}
else
{
GLuint i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
if (mask) {
for (i=0; i<n; i++)
if (mask[i])
Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
}
else {
for (i=0; i<n; i++)
Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
}
}
ENDPROFILE(write_color_span)
}
/*
* Write a horizontal span of pixels with a boolean mask. The current color
* is used for all pixels.
*/
static void write_monocolor_span( GLcontext* ctx,
GLuint n, GLint x, GLint y,
const GLubyte mask[])
{
STARTPROFILE
GLuint i;
HDC DC=DD_GETDC;
PWMC pwc = Current;
assert(Current->rgb_flag==GL_TRUE);
y=FLIP(y);
if(Current->rgb_flag==GL_TRUE){
for (i=0; i<n; i++)
if (mask[i])
// Trying
wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
}
else {
for (i=0; i<n; i++)
if (mask[i])
SetPixel(DC, y, x+i, Current->pixel);
}
DD_RELEASEDC;
ENDPROFILE(write_monocolor_span)
}
/**********************************************************************/
/***** Array-based pixel drawing *****/
/**********************************************************************/
/* Write an array of pixels with a boolean mask. */
static void write_index_pixels( GLcontext* ctx,
GLuint n, const GLint x[], const GLint y[],
const GLuint index[], const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++) {
if (mask[i]) {
char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
*Mem = index[i];
}
}
ENDPROFILE(write_index_pixels)
}
/*
* Write an array of pixels with a boolean mask. The current color
* index is used for all pixels.
*/
static void write_monoindex_pixels( GLcontext* ctx,
GLuint n,
const GLint x[], const GLint y[],
const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++) {
if (mask[i]) {
char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
*Mem = Current->pixel;
}
}
ENDPROFILE(write_monoindex_pixels)
}
/* Write an array of pixels with a boolean mask. */
static void write_color_pixels( GLcontext* ctx,
GLuint n, const GLint x[], const GLint y[],
const GLubyte r[], const GLubyte g[],
const GLubyte b[], const GLubyte a[],
const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
PWMC pwc = Current;
HDC DC=DD_GETDC;
assert(Current->rgb_flag==GL_TRUE);
for (i=0; i<n; i++)
if (mask[i])
wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
DD_RELEASEDC;
ENDPROFILE(write_color_pixels)
}
/*
* Write an array of pixels with a boolean mask. The current color
* is used for all pixels.
*/
static void write_monocolor_pixels( GLcontext* ctx,
GLuint n,
const GLint x[], const GLint y[],
const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
PWMC pwc = Current;
HDC DC=DD_GETDC;
assert(Current->rgb_flag==GL_TRUE);
for (i=0; i<n; i++)
if (mask[i])
wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
GetGValue(Current->pixel), GetBValue(Current->pixel));
DD_RELEASEDC;
ENDPROFILE(write_monocolor_pixels)
}
/**********************************************************************/
/***** Read spans/arrays of pixels *****/
/**********************************************************************/
/* Read a horizontal span of color-index pixels. */
static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
{
STARTPROFILE
GLuint i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++)
index[i]=Mem[i];
ENDPROFILE(read_index_span)
}
/* Read an array of color index pixels. */
static void read_index_pixels( GLcontext* ctx,
GLuint n, const GLint x[], const GLint y[],
GLuint indx[], const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++) {
if (mask[i]) {
indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
}
}
ENDPROFILE(read_index_pixels)
}
/* Read a horizontal span of color pixels. */
static void read_color_span( GLcontext* ctx,
GLuint n, GLint x, GLint y,
GLubyte red[], GLubyte green[],
GLubyte blue[], GLubyte alpha[] )
{
STARTPROFILE
UINT i;
COLORREF Color;
HDC DC=DD_GETDC;
assert(Current->rgb_flag==GL_TRUE);
y=FLIP(y);
for (i=0; i<n; i++)
{
Color=GetPixel(DC,x+i,y);
red[i]=GetRValue(Color);
green[i]=GetGValue(Color);
blue[i]=GetBValue(Color);
alpha[i]=255;
}
DD_RELEASEDC;
memset(alpha,0,n*sizeof(GLint));
ENDPROFILE(read_color_span)
}
/* Read an array of color pixels. */
static void read_color_pixels( GLcontext* ctx,
GLuint n, const GLint x[], const GLint y[],
GLubyte red[], GLubyte green[],
GLubyte blue[], GLubyte alpha[],
const GLubyte mask[] )
{
STARTPROFILE
GLuint i;
COLORREF Color;
HDC DC=DD_GETDC;
assert(Current->rgb_flag==GL_TRUE);
for (i=0; i<n; i++) {
if (mask[i]) {
Color=GetPixel(DC,x[i],FLIP(y[i]));
red[i]=GetRValue(Color);
green[i]=GetGValue(Color);
blue[i]=GetBValue(Color);
alpha[i]=255;
}
}
DD_RELEASEDC;
memset(alpha,0,n*sizeof(GLint));
ENDPROFILE(read_color_pixels)
}
/**********************************************************************/
/**********************************************************************/
void setup_DD_pointers( GLcontext* ctx )
{
ctx->Driver.Finish = finish;
ctx->Driver.Flush = flush;
ctx->Driver.ClearIndex = clear_index;
ctx->Driver.ClearColor = clear_color;
ctx->Driver.Clear = clear;
ctx->Driver.Index = set_index;
ctx->Driver.Color = set_color;
ctx->Driver.IndexMask = index_mask;
ctx->Driver.ColorMask = color_mask;
ctx->Driver.LogicOp = logicop;
ctx->Driver.Dither = dither;
ctx->Driver.SetBuffer = set_buffer;
ctx->Driver.GetBufferSize = buffer_size;
ctx->Driver.PointsFunc = choose_points_function(ctx);
ctx->Driver.LineFunc = choose_line_function(ctx);
ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
// ctx->Driver.TriangleFunc = choose_polygon_function(ctx);
/* Pixel/span writing functions: */
ctx->Driver.WriteColorSpan = write_color_span;
ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
ctx->Driver.WriteColorPixels = write_color_pixels;
ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
ctx->Driver.WriteIndexSpan = write_index_span;
ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
ctx->Driver.WriteIndexPixels = write_index_pixels;
ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
/* Pixel/span reading functions: */
ctx->Driver.ReadIndexSpan = read_index_span;
ctx->Driver.ReadColorSpan = read_color_span;
ctx->Driver.ReadIndexPixels = read_index_pixels;
ctx->Driver.ReadColorPixels = read_color_pixels;
}
//
// MesaGL32 is the DLL version of MesaGL for Win32
//
/**********************************************************************/
/***** WMesa API Functions *****/
/**********************************************************************/
#define PAL_SIZE 256
static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
{
STARTPROFILE
int i;
HDC hdc;
struct
{
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[PAL_SIZE];
} Palette =
{
0x300,
PAL_SIZE
};
hdc=GetDC(NULL);
if (Pal!=NULL)
GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
else
GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
{
for(i = 0; i <PAL_SIZE; i++)
Palette.aEntries[i].peFlags = PC_RESERVED;
Palette.aEntries[255].peRed = 255;
Palette.aEntries[255].peGreen = 255;
Palette.aEntries[255].peBlue = 255;
Palette.aEntries[255].peFlags = 0;
Palette.aEntries[0].peRed = 0;
Palette.aEntries[0].peGreen = 0;
Palette.aEntries[0].peBlue = 0;
Palette.aEntries[0].peFlags = 0;
}
else
{
int nStaticColors;
int nUsableColors;
nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
for (i=0; i<nStaticColors; i++)
Palette.aEntries[i].peFlags = 0;
nUsableColors = PAL_SIZE-nStaticColors;
for (; i<nUsableColors; i++)
Palette.aEntries[i].peFlags = PC_RESERVED;
for (; i<PAL_SIZE-nStaticColors; i++)
Palette.aEntries[i].peFlags = PC_RESERVED;
for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
Palette.aEntries[i].peFlags = 0;
}
ReleaseDC(NULL,hdc);
for (i=0; i<PAL_SIZE; i++)
{
aRGB[i].rgbRed=Palette.aEntries[i].peRed;
aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
}
ENDPROFILE(GetPalette)
}
WMesaContext /*APIENTRY*/ WMesaCreateContext( HWND hWnd, HPALETTE Pal,
/*HDC hDC,*/ GLboolean rgb_flag,
GLboolean db_flag )
{
BITMAPINFO *Rec;
//HDC DC;
RECT CR;
WMesaContext c;
c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
if (!c)
return NULL;
c->Window=hWnd;
c->hDC = GetDC(hWnd);
if (rgb_flag==GL_FALSE)
{
c->rgb_flag = GL_FALSE;
c->pixel = 1;
db_flag=GL_TRUE; // WinG requires double buffering
//c->gl_ctx->BufferDepth = windepth;
}
else
{
c->rgb_flag = GL_TRUE;
c->pixel = 0;
}
GetClientRect(c->Window,&CR);
c->width=CR.right;
c->height=CR.bottom;
if (db_flag)
{
c->db_flag = 1;
// c->hDC GetDC(c->Window);
/* Double buffered */
if (c->rgb_flag==GL_TRUE)
{
//DC = c->hDC = hDC;
// DC = c->hDC = GetDC(c->Window);
wmCreateBackingStore(c, c->width, c->height);
// ReleaseDC(c->Window,DC);
}
else
{
c->dib.hDC=WinGCreateDC();
Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
c->hPal=Pal;
GetPalette(Pal,Rec->bmiColors);
WinGRecommendDIBFormat(Rec);
Rec->bmiHeader.biWidth=c->width;
Rec->bmiHeader.biHeight*=c->height;
Rec->bmiHeader.biClrUsed=PAL_SIZE;
if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
{
MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
exit(1);
}
c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem));
c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM);
WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors);
c->IndexFormat=Rec;
c->ScanWidth=c->width;
c->cColorBits = 8;
if ((c->ScanWidth%sizeof(long))!=0)
c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
}
}
else
{
/* Single Buffered */
c->db_flag = 0;
// wmCreateBackingStore(c, c->width, c->height);
}
c->gl_visual = gl_create_visual(rgb_flag,
GL_FALSE, /* software alpha */
db_flag, /* db_flag */
16, /* depth_bits */
8, /* stencil_bits */
8, /* accum_bits */
8,
255.0, 255.0, 255.0, 255.0 );
if (!c->gl_visual) {
return NULL;
}
/* allocate a new Mesa context */
c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);
if (!c->gl_ctx) {
gl_destroy_visual( c->gl_visual );
free(c);
return NULL;
}
c->gl_buffer = gl_create_framebuffer( c->gl_visual );
if (!c->gl_buffer) {
gl_destroy_visual( c->gl_visual );
gl_destroy_context( c->gl_ctx );
free(c);
return NULL;
}
// setup_DD_pointers(c->gl_ctx);
return c;
}
void /*APIENTRY*/ WMesaDestroyContext( void )
{
WMesaContext c = Current;
ReleaseDC(c->Window,c->hDC);
WC = c;
gl_destroy_visual( c->gl_visual );
gl_destroy_framebuffer( c->gl_buffer );
gl_destroy_context( c->gl_ctx );
if (c->db_flag){
wmDeleteBackingStore(c);
//Code added by Li Wei to enable parallel render
#if !defined(NO_STEREO)
if(stereoBuffer==GL_TRUE){
WMesaDestroyStereoBuffer();
stereoBuffer=GL_FALSE;
}
#endif
// End modification
}
free( (void *) c );
//Code added by Li Wei to enable parallel render
// Parallel render only work in double buffer mode
#if !defined(NO_PARALLEL)
if(parallelMachine)
PRDestroyRenderBuffer();
#endif
// End modification
}
void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
{
if(!c){
Current = c;
return;
}
//
// A little optimization
// If it already is current,
// don't set it again
//
if(Current == c)
return;
//gl_set_context( c->gl_ctx );
gl_make_current(c->gl_ctx, c->gl_buffer);
Current = c;
setup_DD_pointers(c->gl_ctx);
if (Current->gl_ctx->Viewport.Width==0) {
/* initialize viewport to window size */
gl_Viewport( Current->gl_ctx,
0, 0, Current->width, Current->height );
}
}
void /*APIENTRY*/ WMesaSwapBuffers( void )
{
HDC DC = Current->hDC;
if (Current->db_flag)
{
if (Current->rgb_flag)
wmFlush(Current);
else
WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0);
}
}
void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
{
if (Current && Current->rgb_flag==GL_FALSE)
{
Current->hPal=Pal;
GetPalette(Pal,Current->IndexFormat->bmiColors);
WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
}
}
//
// Free up the dib section that was created
//
BOOL wmDeleteBackingStore(PWMC pwc)
{
SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
DeleteDC(pwc->dib.hDC);
DeleteObject(pwc->hbmDIB);
UnmapViewOfFile(pwc->dib.base);
CloseHandle(pwc->dib.hFileMap);
return TRUE;
}
//
// This function creates the DIB section that is used for combined
// GL and GDI calls
//
BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
{
HDC hdc = pwc->hDC;
LPBITMAPINFO pbmi = &(pwc->bmi);
int iUsage;
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = lxSize;
pbmi->bmiHeader.biHeight= -lySize;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 0;
pbmi->bmiHeader.biXPelsPerMeter = 0;
pbmi->bmiHeader.biYPelsPerMeter = 0;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;
iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
pwc->cColorBits = pbmi->bmiHeader.biBitCount;
pwc->ScanWidth = lxSize;
wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
wmCreatePalette( pwc );
wmSetDibColors( pwc );
}
return(TRUE);
}
//
// This function copies one scan line in a DIB section to another
//
BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
{
UINT uiScans = 0;
LPBYTE pDest = pwc->pbPixels;
DWORD dwNextScan = uiScanWidth;
DWORD dwNewScan = uiNewWidth;
DWORD dwScanWidth = (uiScanWidth * nBypp);
//
// We need to round up to the nearest DWORD
// and multiply by the number of bytes per
// pixel
//
dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
for(uiScans = 0; uiScans < uiNumScans; uiScans++){
CopyMemory(pDest, pBits, dwScanWidth);
pBits += dwNextScan;
pDest += dwNewScan;
}
return(TRUE);
}
BOOL WINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags )
{
return(TRUE);
}
static unsigned char threeto8[8] = {
0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
};
static unsigned char twoto8[4] = {
0, 0x55, 0xaa, 0xff
};
static unsigned char oneto8[2] = {
0, 255
};
static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
{
unsigned char val;
val = i >> shift;
switch (nbits) {
case 1:
val &= 0x1;
return oneto8[val];
case 2:
val &= 0x3;
return twoto8[val];
case 3:
val &= 0x7;
return threeto8[val];
default:
return 0;
}
}
void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
{
/* Create a compressed and re-expanded 3:3:2 palette */
int i;
LOGPALETTE *pPal;
BYTE rb, rs, gb, gs, bb, bs;
pwdc->nColors = 0x100;
pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
pPal->palVersion = 0x300;
rb = REDBITS;
rs = REDSHIFT;
gb = GREENBITS;
gs = GREENSHIFT;
bb = BLUEBITS;
bs = BLUESHIFT;
if (pwdc->db_flag) {
/* Need to make two palettes: one for the screen DC and one for the DIB. */
pPal->palNumEntries = pwdc->nColors;
for (i = 0; i < pwdc->nColors; i++) {
pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
pPal->palPalEntry[i].peFlags = 0;
}
pwdc->hGLPalette = CreatePalette( pPal );
pwdc->hPalette = CreatePalette( pPal );
}
else {
pPal->palNumEntries = pwdc->nColors;
for (i = 0; i < pwdc->nColors; i++) {
pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
pPal->palPalEntry[i].peFlags = 0;
}
pwdc->hGLPalette = CreatePalette( pPal );
}
free(pPal);
}
//
// This function sets the color table of a DIB section
// to match that of the destination DC
//
BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
{
RGBQUAD *pColTab, *pRGB;
PALETTEENTRY *pPal, *pPE;
int i, nColors;
BOOL bRet=TRUE;
DWORD dwErr=0;
/* Build a color table in the DIB that maps to the
selected palette in the DC.
*/
nColors = 1 << pwc->cColorBits;
pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
pRGB->rgbRed = pPE->peRed;
pRGB->rgbGreen = pPE->peGreen;
pRGB->rgbBlue = pPE->peBlue;
}
if(pwc->db_flag)
bRet = SetDIBColorTable(pwc->hDC, 0, nColors, pColTab );
if(!bRet)
dwErr = GetLastError();
free( pColTab );
free( pPal );
return(bRet);
}
void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
{
if(Current->db_flag){
LPBYTE lpb = pwc->pbPixels;
LPDWORD lpdw;
LPWORD lpw;
UINT nBypp = pwc->cColorBits / 8;
UINT nOffset = iPixel % nBypp;
// Move the pixel buffer pointer to the scanline that we
// want to access
pwc->dib.fFlushed = FALSE;
lpb += pwc->ScanWidth * iScanLine;
// Now move to the desired pixel
lpb += iPixel * nBypp;
lpdw = (LPDWORD)lpb;
lpw = (LPWORD)lpb;
if(nBypp == 2)
*lpw = BGR16(r,g,b);
else if (nBypp == 3){
*lpdw = BGR24(r,g,b);
}
else
*lpdw = BGR32(r,g,b);
}
else{
HDC DC = DD_GETDC;
SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
DD_RELEASEDC;
}
}
void /*WINAPI*/ wmCreateDIBSection(
HDC hDC,
PWMC pwc, // handle of device context
CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
UINT iUsage // color data type indicator: RGB values or palette indices
)
{
DWORD dwSize = 0;
DWORD dwScanWidth;
UINT nBypp = pwc->cColorBits / 8;
HDC hic;
dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
pwc->ScanWidth = dwScanWidth;
dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
NULL,
PAGE_READWRITE | SEC_COMMIT,
0,
dwSize,
NULL);
if (!pwc->dib.hFileMap)
return;
pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if(!pwc->dib.base){
CloseHandle(pwc->dib.hFileMap);
return;
}
pwc->pbPixels = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
pwc->dib.hDC = CreateCompatibleDC(hDC);
CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
hic = CreateIC("display", NULL, NULL, NULL);
/* pwc->hbmDIB = CreateDIBitmap(hic,
&(pwc->bmi.bmiHeader),
CBM_INIT,
pwc->pbPixels,
&(pwc->bmi),
DIB_RGB_COLORS);
*/
pwc->hbmDIB = CreateDIBSection(hic,
&(pwc->bmi.bmiHeader),
DIB_RGB_COLORS,
&(pwc->pbPixels),
pwc->dib.hFileMap,
0);
pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
DeleteDC(hic);
return;
}
//
// Blit memory DC to screen DC
//
BOOL /*WINAPI*/ wmFlush(PWMC pwc)
{
BOOL bRet = 0;
DWORD dwErr = 0;
// wmFlushBits(pwc);
bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
pwc->dib.hDC, 0, 0, SRCCOPY);
if(!bRet)
dwErr = GetLastError();
pwc->dib.fFlushed = TRUE;
return(TRUE);
}
// The following code is added by Li Wei to enable stereo display
#if !defined(NO_STEREO)
void WMesaCreateStereoBuffer()
{
/* Must use double buffer and not in parallelMode */
if (! Current->db_flag
#if !defined(NO_PARALLEL)
|| parallelFlag
#endif
)
return;
Buffer_Stereo = malloc( Current->ScanWidth * Current->height);
ZeroMemory(Buffer_Stereo,Current->ScanWidth * Current->height);
stereoBuffer = GL_TRUE ;
}
void WMesaDestroyStereoBuffer()
{
/* Must use double buffer and not in parallelMode */
if (! Current->db_flag
#if !defined(NO_PARALLEL)
|| parallelFlag
#endif
)
return;
if(stereoBuffer){
free(Buffer_Stereo);
stereoBuffer = GL_FALSE ;
}
}
void WMesaInterleave(GLenum aView)
{
int offset;
unsigned line;
LPBYTE dest;
LPBYTE src;
if(aView == FIRST)
offset = 0;
else offset = 1;
dest = Buffer_Stereo + offset * Current->ScanWidth;
if(Current->rgb_flag )
src = Current->pbPixels + Current->ScanWidth*(Current->height/2);
else
src = Current->ScreenMem;
for(line = 0; line<Current->height/2; line ++){
CopyMemory(dest, src, Current->ScanWidth);
dest += 2*Current->ScanWidth;
src += Current->ScanWidth;
}
if(aView == SECOND)
if(Current->rgb_flag)
CopyMemory(Current->pbPixels, Buffer_Stereo, Current->ScanWidth*Current->height);
else
CopyMemory(Current->ScreenMem, Buffer_Stereo, Current->ScanWidth*Current->height);
}
void WMesaShowStereo(GLuint list)
{
GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
GLfloat cm[16];
// Must use double Buffer
if( ! Current-> db_flag )
return;
glViewport(0,0,Current->width,Current->height/2);
glGetFloatv(GL_MODELVIEW_MATRIX,cm);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(viewDistance/2,0.0,0.0 ,
viewDistance/2,0.0,-1.0,
0.0,1.0,0.0 );
glMultMatrixf( cm );
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glCallList( list );
glPopMatrix();
glFlush();
WMesaInterleave( FIRST );
glGetFloatv(GL_MODELVIEW_MATRIX,cm);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(-viewDistance/2,0.0,0.0 ,
-viewDistance/2,0.0,-1.0,
0.0,1.0,0.0 );
glMultMatrixf(cm);
glMatrixMode(GL_MODELVIEW);
glCallList(list);
glFlush();
WMesaInterleave( SECOND );
glViewport(0,0,Current->width,Current->height);
WMesaSwapBuffers();
}
void toggleStereoMode()
{
if(!Current->db_flag)
return;
if(!stereo_flag){
stereo_flag = 1;
if(stereoBuffer==GL_FALSE)
#if !defined(NO_PARALLEL)
if(!parallelFlag)
#endif
{
WMesaCreateStereoBuffer();
}
}
else {
stereo_flag = 0;
if(stereoBuffer==GL_TRUE)
#if !defined(NO_PARALLEL)
if(!parallelFlag)
#endif
if(stereoBuffer==GL_TRUE){
WMesaDestroyStereoBuffer();
}
}
}
/* if in stereo mode, the following function is called */
void glShowStereo(GLuint list)
{
WMesaShowStereo(list);
}
#endif // End if NO_STEREO not defined
#if !defined(NO_PARALLEL)
void toggleParallelMode(void)
{
if(!parallelFlag){
parallelFlag = GL_TRUE;
if(parallelMachine==GL_FALSE){
PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
Current->cColorBits/8,
Current->width ,Current->height,
Current->ScanWidth,
Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
parallelMachine = GL_TRUE;
}
}
else {
parallelFlag = GL_FALSE;
if(parallelMachine==GL_TRUE){
PRDestroyRenderBuffer();
parallelMachine=GL_FALSE;
ReadyForNextFrame = GL_TRUE;
}
/***********************************************
// Seems something wrong!!!!
************************************************/
WMesaMakeCurrent(Current);
#if !defined(NO_STEREO)
stereo_flag = GL_FALSE ;
#endif
}
}
void PRShowRenderResult(void)
{
int flag = 0;
if(!glImageRendered())
return;
if (parallelFlag)
{
WMesaSwapBuffers();
}
}
#endif //End if NO_PARALLEL not defined
//end modification